home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Utilities / GOCR / src / pcx.cc < prev    next >
C/C++ Source or Header  |  2000-03-25  |  5KB  |  132 lines

  1. // Joerg Schulenburg Mai99
  2.  
  3. #include <stdio.h>
  4. // #include <stdlib.h>
  5. // #include <assert.h>
  6.  
  7. #include "pcx.h"
  8.  
  9. typedef unsigned char byte;
  10.  
  11. #define ERR(x) { fprintf(stderr,"ERROR "__FILE__" L%d: " x "\n",__LINE__);exit(1);}
  12.  
  13. int err;
  14. // --- needed for reading PCX-files
  15. char read_b(FILE *f1){
  16.   char c=0; c=fgetc(f1); if(feof(f1) || ferror(f1))err=1; return c;
  17. }
  18.  
  19. // something here is wrong!
  20. void readpcx(char *name,pix *p,int vvv){         // see pcx.format.txt
  21.   int page,pages,nx,ny,i,j,b,x,y,bpl,bits,pal[256][3];
  22.   FILE *f1;  
  23.   unsigned char *pic,h[128],bb,b1,b2,b3;
  24.   err=0;
  25.   for(i=0;i<256;i++)for(j=0;j<3;j++)pal[i][j]=i;
  26.   f1=fopen(name,"rb"); if(!f1) ERR("open");
  27.   if(fread(h,1,128,f1)!=128)ERR("read PCX header");    /* 128 Byte lesen -> h[] */
  28.   if(h[0]!=10)ERR("no ZSoft sign");    // ZSoft sign
  29.   if(h[2]>  1)ERR("unknown coding");    // run length encoding
  30.   bits = h[3];        // 1 or 8
  31.   if(bits!=1 && bits!=8)ERR("only 1 or 8 bits supported");
  32.   nx = h[ 9]*256+h[ 8] - h[ 5]*256-h[ 4] +1;    // Xmax-Xmin
  33.   ny = h[11]*256+h[10] - h[ 7]*256-h[ 6] +1;    // Ymax-Ymin
  34.   pages=h[65]; bpl=h[66]+256*h[67]; // bytes per line
  35.   if(vvv)
  36.   printf("# PCX version=%d bits=%d x=%d y=%d HRes=%d VRes=%d\n"
  37.          "# NPlanes=%d BytesPerLine=%d Palette=%s",
  38.     h[1],bits,nx,ny,h[12]+256*h[13],h[14]+256*h[15],
  39.     pages,bpl,((h[68]==1)?"1=color/bw":"2=gray"));
  40.   //  line1(NP=4): RRRRR...,GGGG....,BBBBB...,IIII...., line2: RRRR...,GGGG....
  41.   //  C4 EF = (C4&3F)*EF = EF EF EF EF
  42.   fflush(stdout);
  43.   // palette: for(i=0;i<16;i++) for(j=0;j<3;j++) h[16+3*i+j] 
  44.   if(pages>1)for(b=0;b<16;b++) for(i=0;i<16;i++)
  45.              for(j=0;j< 3;j++) pal[b*16+i][j]=h[16+3*i+j]>>2;
  46.   if(bits>7){
  47.    fseek(f1,-3*256,2); if(fread(pal,3,256,f1)!=256)ERR("read palette");
  48.    for(i=0;i<256;i++) for(j=0;j<3;j++) pal[i][j]>>=2;
  49.   }
  50.   fseek(f1,128,0);
  51.   // pic=new Uchar[ (*nx)*(*ny) ];        // errors!
  52.   pic=new unsigned char[ nx*ny ];
  53.   if(pic==NULL)ERR("no memory");        // no memory
  54.   x=y=0;
  55.   do {
  56.     for(page=0;page<pages;page++)    // 192 == 0xc0 => b1=counter
  57.     do {
  58.       b1=1; bb=read_b(f1); b2=bb; if(b1==192)printf("?");
  59.       if((b2>=192) && (h[2]==1)){b1=b2&63;bb=read_b(f1);b2=bb;}
  60.       if(err){fprintf(stderr,"\nread error x=%d y=%d\n",x,y);x=nx;y=ny;break;}
  61.       for(b3=0;b3<b1;b3++)for(b=0;b<8;b+=bits,x++)if(x<nx){
  62.         bb=(b2>>(8-bits-b)) & ~((~0)<<bits);
  63.         if(bits==1 && bb==1) bb=240;
  64.         if(page==0) pic[x+nx*y] =(byte)bb;
  65.         else        pic[x+nx*y]|=(byte)bb<<(page*bits);
  66.       }
  67.     } while(x<(9-bits)*bpl);  x=0; y++;
  68.   } while(y<ny); 
  69.   /*  */
  70.   fclose(f1);
  71.   p->p=pic;  p->x=nx;  p->y=ny; p->bpp=1;
  72.   if(vvv)printf("\n");
  73. }
  74.  
  75. // ------------------------------------------------------------------------
  76.  
  77. // write bmp 8bit palette no RLE 
  78. void writebmp(char *name,pix p,int vvv){     // see pcx.format.txt
  79.   int nx,ny,i,y,rest[4]={0,0,0,0};
  80.   FILE *f1;  
  81.   static unsigned char *pic,h[54+4*256];
  82.   long fs,fo,hs,is;    // filesize, offset, headersize, imagesize
  83.  
  84.   nx=p.x; ny=p.y; pic=p.p;
  85.   hs=40;        // bmi headersize fix
  86.   is=((nx+3)&3)*ny; // imagesize
  87.   fo=14+hs+4*256;
  88.   fs=fo+is;
  89.   for(i=0;i<54;i++){ h[i]=0; }
  90.   // BITMAPFILEHEADER
  91.   h[ 0]='B';          h[ 1]='M';         // type of file BMP
  92.   h[ 2]= fs     &255; h[ 3]=(fs>> 8)&255;
  93.   h[ 4]=(fs>>16)&255; h[ 5]=(fs>>24)&255;    // size of file
  94.   h[10]= fo     &255; h[11]=(fo>> 8)&255;
  95.   h[12]=(fo>>16)&255; h[13]=(fo>>24)&255;    // offset to image data
  96.   // BITMAPINFO  (BITMAPCOREHEADER not used here)
  97.   // 14 - HEADER
  98.   h[14]= hs     &255; h[15]=(hs>> 8)&255;
  99.   h[16]=(hs>>16)&255; h[17]=(hs>>24)&255;    // bmi-header size
  100.   h[18]= nx     &255; h[19]=(nx>> 8)&255;
  101.   h[20]=(0l>>16)&255; h[21]=(0l>>24)&255;    // WIDTH/pixel
  102.   h[22]= ny     &255; h[23]=(ny>> 8)&255;
  103.   h[24]=(0l>>16)&255; h[25]=(0l>>24)&255;    // HIGH/pixel
  104.   h[26]=1;                            // planes
  105.   h[28]=8;                            // bits/pixel 1,4,8,24
  106.   h[30]=0;                            // compression
  107.   h[34]= is     &255; h[35]=(is>> 8)&255;
  108.   h[36]=(is>>16)&255; h[37]=(is>>24)&255;    // sizeImage (can be 0 if ~RLE)
  109.   h[38]=0;h[39]=1;    // ca 100dpi, x/meter
  110.   h[42]=0;h[43]=1;    //           y/meter
  111.   h[46]=0;h[47]=1;    // colorused (0=maximum)
  112.   h[50]=0;h[51]=1;    // colorimportand (0=all)
  113.   // 54 - endofheader
  114.   for(i=0;i<256;i++){ 
  115.      h[54+4*i+0]=(~((i & 16)*8)) &                   (i & 128+64)|63;
  116.      h[54+4*i+1]=(~((i & 16)*8)) & (~((i & 32)*4)) & (i & 128+64)|63;
  117.      h[54+4*i+2]=                  (~((i & 32)*4)) & (i & 128+64)|63;
  118.   }             // blue-green-red
  119.   f1=fopen(name,"wb"); if(!f1) printf(" error opening file\n");
  120.   if(!f1)ERR("open");        // open-error
  121.   if(fwrite(h,1,54+4*256,f1)!=54+4*256)ERR("write head"); 
  122.   if(vvv) printf("# write BMP x=%d y=%d\n",nx,ny);
  123.   for(y=ny-1;y>=0;y--){
  124.     if(((int)fwrite(pic+nx*y,1,nx,f1))!=nx)ERR("write");
  125.     if(nx&3)
  126.     if(((int)fwrite(rest,1,4-(nx&3),f1))!=4-(nx&3))ERR("write");  // must be mod4
  127.   }
  128.   fclose(f1);
  129. }
  130.  
  131. // ------------------------------------------------------------------------
  132.